package Tests;
import java.io.*;
import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.stream.*;
import javax.xml.stream.events.XMLEvent;

public class Merger {

	private static final QName prodName = new QName("product");
	private static final QName pidName = new QName("pid");
	public static URL caminho1;
	public static URL caminho2;
	
	Merger(){
		caminho1 = getClass().getResource("/Tests/prodList1.xml");
		caminho2 = getClass().getResource("/Tests/prodList2.xml");
	}
	
	public static void main(String[] args) throws FileNotFoundException, XMLStreamException {				
		Merger merger = new Merger();
		System.out.println(caminho1.toString().substring(6, caminho1.toString().length()));
		
		// Use  the reference implementation for the  XML input factory
		System.setProperty(
			"javax.xml.stream.XMLInputFactory",
			"com.bea.xml.stream.MXParserFactory");
		// Create the XML input factory
		XMLInputFactory factory = XMLInputFactory.newInstance();
		// Create XML event reader 1
		XMLEventReader r1 =
			factory.createXMLEventReader(new FileReader(caminho1.toString().substring(6, caminho1.toString().length())));
		// Create XML event reader 2
		XMLEventReader r2 =
			factory.createXMLEventReader(new FileReader(caminho2.toString().substring(6, caminho1.toString().length())));

		// Create the output factory
		XMLOutputFactory xmlof = XMLOutputFactory.newInstance();
		// Create XML event writer
		XMLEventWriter xmlw = xmlof.createXMLEventWriter(System.out);

		// Read to first <product> element in document 1
		// and output to result document
		String pid1 = readToNextElement(r1, xmlw, false);
		// Read to first <product> element in document 1
		// without writing to result document
		String pid2 = readToNextElement(r2, null, false);
		// Loop over both XML input streams
		while (pid1 != null || pid2 != null) {
			// Compare merge criteria
			if (pid2 == null || (pid1 != null && pid1.compareTo(pid2) <= 0))
				// Continue in document 1
				pid1 = readToNextElement(r1, xmlw, pid2 == null);
			else
				// Continue in document 2
				pid2 = readToNextElement(r2, xmlw, pid1 == null);
		}
		xmlw.close();
	}

	/**
		* @param reader - the document reader
		* @param writer - the document writer
		* @param processEnd � forces the document end to be written
		* @return - the next merge criterion value
		* @throws XMLStreamException
		*/
	private static String readToNextElement(
		XMLEventReader reader,
		XMLEventWriter writer,
		boolean processEnd)
		throws XMLStreamException {
		// Nesting level
		int level = 0;
		while (true) {
			// Read event to be written to result document
			XMLEvent event = (XMLEvent) reader.next();
			// Avoid double processing of document end
			if (!processEnd)
				switch (event.getEventType()) {
					case XMLEvent.START_ELEMENT :
						++level;
						break;
					case XMLEvent.END_ELEMENT :
						if (--level < 0)
							return null;
						break;
				}
			// Output event
			if (writer != null)
				writer.add(event);
			// Look at next event
			event = reader.peek();
			switch (event.getEventType()) {
				case XMLEvent.START_ELEMENT :
					// Start element - stop at <product> element
					QName name = event.asStartElement().getName();
					if (name.equals(prodName)) {
						return event
							.asStartElement()
							.getAttributeByName(pidName)
							.getValue();
					}
					break;
				case XMLEvent.END_DOCUMENT :
					// Stop at end of document
					return null;
			}
		}
	}
}